package com.zkh.myutils.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 中文数字和阿拉伯数字互换
 * @author zkh
 */
public class NumberTransfer {
	
	private static long result = 0;
    // HashMap
    private static Map<String, Long> unitMap = new HashMap<String, Long>();
    private static Map<String, Long> numMap = new HashMap<String, Long>();

    // 字符串分离
    private static String stryi = new String();
    private static String stryiwan = new String();
    private static String stryione = new String();
    private static String strwan = new String();
    private static String strone = new String();

    // 组合数字
    public static long chnToNum(String chnStr) {
        ChangeChnString(chnStr);
        long stryiwanresult = chnStrToNum(stryiwan);
        long stryioneresult = chnStrToNum(stryione);
        long strwanresult = chnStrToNum(strwan);
        long stroneresult = chnStrToNum(strone);
        result = (stryiwanresult + stryioneresult) * 100000000 + strwanresult * 10000 + stroneresult;
        // 重置
        stryi = "";
        strwan = "";
        strone = "";
        return result;
    }
    
	/**
	 * 阿拉伯数字转中文数字
	 */
	public static String numToChn(long num){
		if(num==0) return "零";
		//保存参数副本
		long temp = num;
		//保存结果
		StringBuilder result = new StringBuilder();
		//转换的数字不能超过千亿级
		if(num>999999999999L){
			throw new RuntimeException("转换的数字不能超过千亿级！");
		}
		//保存级数，从低级开始
		List<Long> rank = new ArrayList<Long>();
		while(temp>0){
			//从后到前依次将各级别的数字放入集合
			rank.add(temp%10000);
			temp /= 10000;
		}
		//数量级
		String[] ranks = {"","万","亿"};
		//将每一级转化为中文
		for(int i=0,len=rank.size();i<len;i++){
			//临时字符串
			String t = "";
			//获取转换后的字符串
			String format = formatrank(rank.get(i));
			t += format;
			//是否添加单位
			if(!format.isEmpty() && !"零".equals(format)){
				t += ranks[i];
			}
			result.insert(0, t);
		}
		//去除开头或结尾的零，去除以一十开始的字符串，返回结果
		return result.toString().replaceAll("^零+|零+$", "").replaceAll("^一(十.+$)", "$1");
	}

    private static void ChangeChnString(String chnStr) {
        // unit
        unitMap.put("十", 10L);
        unitMap.put("百", 100L);
        unitMap.put("千", 1000L);
        unitMap.put("万", 10000L);
        unitMap.put("亿", 100000000L);
        // num
        numMap.put("零", 0L);
        numMap.put("一", 1L);
        numMap.put("二", 2L);
        numMap.put("三", 3L);
        numMap.put("四", 4L);
        numMap.put("五", 5L);
        numMap.put("六", 6L);
        numMap.put("七", 7L);
        numMap.put("八", 8L);
        numMap.put("九", 9L);

        // 去零
        for (int i = 0; i < chnStr.length(); i++) {
            if ('零' == (chnStr.charAt(i))) {
                chnStr = chnStr.substring(0, i) + chnStr.substring(i + 1);
            }
        }
        // 分切成三部分
        int index = 0;
        boolean yiflag = true;
        boolean yiwanflag = true; //亿字节中存在万
        boolean wanflag = true;
        for (int i = 0; i < chnStr.length(); i++) {
            if ('亿' == (chnStr.charAt(i))) {
                // 存在亿前面也有小节的情况
                stryi = chnStr.substring(0, i);
                if (chnStr.indexOf('亿' + "") > chnStr.indexOf('万' + "")) {
                    stryi = chnStr.substring(0, i);
                    for (int j = 0; j < stryi.length(); j++) {
                        if ('万' == (stryi.charAt(j))) {
                            yiwanflag = false;
                            stryiwan = stryi.substring(0, j);
                            stryione = stryi.substring(j + 1);
                        }
                    }
                }
                if(yiwanflag){//亿字节中没有万，直接赋值
                    stryione = stryi;
                }
                index = i + 1;
                yiflag = false;// 分节完毕
                strone = chnStr.substring(i + 1);

            }
            if ('万' == (chnStr.charAt(i)) && chnStr.indexOf('亿' + "") < chnStr.indexOf('万' + "")) {
                strwan = chnStr.substring(index, i);
                strone = chnStr.substring(i + 1);
                wanflag = false;// 分节完毕
            }
        }
        if (yiflag && wanflag) {// 没有处理
            strone = chnStr;
        }
    }

    // 字符串转换为数字
    private static long chnStrToNum(String str) {
        long strreuslt = 0;
        long value1 = 0;
        long value2 = 0;
        long value3 = 0;
        if (str.isEmpty()) {
            return 0;
        }
        for (int i = 0; i < str.length(); i++) {
            char bit = str.charAt(i);
            // 数字
            if (numMap.containsKey(bit + "")) {
                value1 = numMap.get(bit + "");
                if (i == str.length() - 1) {
                    strreuslt += value1;
                }

            }
            // 单位
            else if (unitMap.containsKey(bit + "")) {
                value2 = unitMap.get(bit + "");
                if (value1 == 0 && value2 == 10L) {
                    value3 = 1 * value2;
                } else {
                    value3 = value1 * value2;
                    // 清零避免重复读取
                    value1 = 0;
                }
                strreuslt += value3;
            }
        }
        return strreuslt;
    }
	
	/**
	 * 转换每一级
	 */
	private static String formatrank(long r) {
		//转换结果
		String result = "";
		//转换为整型
		int temp = (int)r;
		//中文数字
		String[] number = {"零","一","二","三","四","五","六","七","八","九"};
		//单位
		String[] init = {"","十","百","千"};
		//计数
		int count = 0;
		while(temp>0){
			//取数字，并转为中文
			String t = number[temp%10];
			//如果不等于零，则加上单位
			if(temp%10 != 0){
				t+=init[count];
			}
			//拼接结果
			result = t + result;
			//计数自增
			count++;
			//移位
			temp /= 10;
		}
		//去除末尾的零和连续的零
		result = result.replaceAll("零+$", "").replaceAll("零+", "零");
		//如果不足四位，则在最前方添加零
		if(r<999){
			result = "零" + result;
		}
		//返回结果
		return result;
	}
}
